#include <iostream>
#include <string>
#include <time.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>

using namespace std;
/*La fonction qui calcule la taille du fichier passé en parametre*/
float calculerTaille(FILE* fichier);


/*La fonction qui teste nom_fic et affiche le résultat dans nom_log*/
void test(char* nom_log, char* nom_fic); 

/*La fonction qui teste (grace a test())tous les fichiers présents dans le répertoire fichiers_tests*/
void testFichiers(char* nom_log);

/*La fonction qui teste (grace a test()) des fichiers aleatoires sur 26 caracteres de taille tmin a tmax par pas de add*/
void testAleatoire(int tmin, int tmax, int add, char* nom_log);




float calculerTaille(FILE* fichier)
{
  fseek(fichier,0,SEEK_END);
  float retour = ftell(fichier);
  rewind(fichier);
  return retour; 
}





void test(char* nom_log, char* nom_fic, char* nom_algo)
{
  FILE* log = fopen(nom_log, "a+");
  if(log == NULL)
    {
      cerr<<"Probleme à l'ouverture du fichier log"<<endl;
      exit(EXIT_FAILURE);
    } 

  FILE* ficBase = fopen(nom_fic, "r");
  if(ficBase == NULL)
    {
      cerr<<"Probleme à l'ouverture du fichier de base"<<endl;
      exit(EXIT_FAILURE);
    }
  float taillefic = calculerTaille(ficBase);
  fclose(ficBase);
  char t[4];
  sprintf(t, "%d", taillefic);
  string ecrit = (string)"Fichier "+nom_fic+"\n";
  fwrite(ecrit.c_str(), 1, strlen(ecrit.c_str()), log);
   
  fclose(log);
  system(((string)"../entro "+nom_fic+" >> " +nom_log).c_str());
  log = fopen(nom_log, "a+");
   
   
  int temps = time(NULL); 
  if(strcmp(nom_algo,"zip"))  
    system(((string)"../compress "+nom_fic+" fichiercompress -c -t "+nom_algo).c_str());
  else
    {
      if(0>unlink("fichiercompress.zip"))
	cout<<"erreur : pas de fichier a supprimer"<<endl;
      system(((string)"zip fichiercompress "+nom_fic).c_str());
    }
  temps = time(NULL) - temps;
   
  ecrit = "\nFichier compressé :\n";
  fwrite(ecrit.c_str(), 1, strlen(ecrit.c_str()), log);
   
  fclose(log);
  string nomComp = "fichiercompress";
  if(!strcmp(nom_algo,"zip"))
    nomComp+=".zip";
  system(((string)"../entro "+nomComp+" >> "+nom_log).c_str());
  log = fopen(nom_log, "a+");

  ecrit = "\n";
  fwrite(ecrit.c_str(), 1, strlen(ecrit.c_str()), log);
  
  FILE* ficComp = fopen(nomComp.c_str(), "r");

  if(ficComp == NULL)
    {
      cerr<<"Probleme à l'ouverture du fichier compressé"<<endl;
      exit(EXIT_FAILURE);
    }
  float taillecomp = calculerTaille(ficComp);
  fclose(ficComp);
 
  int tcompress = (taillecomp/taillefic)*100.0;
  
  char comp[sizeof(int)];
  char tExec[sizeof(int)];
 
  sprintf(comp, "%d", tcompress);
  sprintf(tExec, "%d", temps);
 
  string fin = (string)("Taux de compression : ")+comp+"\nTemps d'execution : "+tExec+"ms\n####################################################\n";

  fwrite(fin.c_str(), 1, strlen(fin.c_str()), log);
  fclose(log);
}







void testFichiers(char* nom_log, char* nom_algo)
{
  DIR* dossier = opendir("fichiers_tests");
  if(dossier == NULL)
    {
      cerr<<"Dossier 'fichiers_tests' attendu..."<<endl;
      exit(EXIT_FAILURE);
    }

  struct dirent* fichier = readdir(dossier);

  while(fichier != NULL)
    { 
      char nom_fic[50];
      strcpy(nom_fic, fichier->d_name);
      char nom[100] = "fichiers_tests/";
      strcat(nom, nom_fic);

      struct stat* buf = new struct stat();

      stat(nom, buf);

      if(S_ISREG(buf->st_mode)) //S'il s'agit d'un fichier régulier...
	{
	  cout<<"Analyse de : "<<nom<<endl;
	  test(nom_log, nom, nom_algo);
	}
      fichier = readdir(dossier);
      delete buf;
    }
  closedir(dossier);
}

void testAleatoire(int tmin, int tmax, int add, char* nom_log, char* nom_algo)
{
  char nlog[50];
  strcat(nlog, nom_log);
  strcat(nlog, "_alea");
  cout<<nlog<<endl;
 
  int tact = tmin;
  while(tact < tmax)
    {
      FILE* ficTest;
      ficTest = fopen("fichierTest", "w+");
      if(ficTest == NULL)
	{
	  cerr<<"Probleme à la création du fichier test"<<endl;
	  exit(EXIT_FAILURE);
	}

      char* texte = new char[tact+1];

      //tests sur l'alphabet (26 caracteres)
      for(int i = 0; i < tact; i++)
	texte[i] = rand()%26 + 97; //pour avoir effectivement des lettres... 
      texte[tact] = '\0';


      if(fwrite(texte, 1, tact, ficTest) < 0)
	{	  
	  cerr<<"Probleme à l'écriture dans le fichier de base"<<endl;
	  exit(EXIT_FAILURE);
	}    
      fclose(ficTest);

      char nom_fichier[50] = "fichierTest";
      test(nlog, nom_fichier, nom_algo);
      tact += add;
      delete ficTest;
      delete texte;
    }
}




int main(int argc, char* argv[])
{
  if(argc >=2)
    {
      char nom_log[50] = "log_tests_";
      strcat(nom_log, argv[1]);
      if(!strcmp(argv[1], "zip") && !strcmp(argv[1], "lz77") && !strcmp(argv[1], "lz78") && !strcmp(argv[1], "huffman") && !strcmp(argv[1], "bzip") && !strcmp(argv[1], "defl"))
	{
	  cout<<"Nom d'algorithme attendu : lz77 | lz78 | bzip | huffman | defl |zip"<<endl;
	  exit(EXIT_SUCCESS);
	}
     
      if(argc == 2)
	{
	  testFichiers(nom_log, argv[1]);
	}
      if(argc == 5)
	{
	  int tmin, tmax, add;
	  tmin = atoi(argv[2]);
	  tmax = atoi(argv[3]);
	  add = atoi(argv[4]);
	  testAleatoire(tmin, tmax, add, nom_log, argv[1]);
	}
    }
  else
    {
      cout<<"Usage : nomAlgo [taillemin taillemax, increment]"<<endl
	  <<"nomalgo : lz78 | lz77 | bzip | huffman | defl | zip"<<endl
	  <<"taillemin : taille de depart de génération de fichiers aléatoires"<<endl
	  <<"taillemax : taille d'arret de generation de fichiers aleatoires"<<endl
	  <<"increment : nombre d'octets supplémentaires entre chaque fichier aléatoire"<<endl;
    }
}
